/*
                        *********************
*************************** C SOURCE FILE ************************************
**                      *********************                               **
**                                                                          **
*/

#define _SERVER_C_SRC

/****************************************************************************/
/**                                                                        **/
/** MODULES USED                                                           **/
/**                                                                        **/
/****************************************************************************/

#include "server.h"

/****************************************************************************/
/**                                                                        **/
/** DEFINITIONS AND MACROS                                                 **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** TYPEDEFS AND STRUCTURES                                                **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** PROTOTYPES OF LOCAL FUNCTIONS                                          **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** EXPORTED VARIABLES                                                     **/
/**                                                                        **/
/****************************************************************************/


/****************************************************************************/
/**                                                                        **/
/** GLOBAL VARIABLES                                                       **/
/**                                                                        **/
/****************************************************************************/



/****************************************************************************/
/**                                                                        **/
/** EXPORTED FUNCTIONS                                                     **/
/**                                                                        **/
/****************************************************************************/



/****************************************************************************/
/**                                                                        **/
/** LOCAL FUNCTIONS                                                        **/
/**                                                                        **/
/****************************************************************************/
int16s main(int16s argc,int8u *argv[])
{
	int16s 	server_sockfd, client_sockfd;
	int16s 	server_len, client_len;
	struct sockaddr_in server_address;
	struct sockaddr_in client_address;
	int16s 	result;
	int16u	nB,i,j;
	int16u	answer;
	int16u 	round = 0;
	int8u 	*buf;
	
	if(argc == 2)
	{
		for(i=0;argv[1][i];i++)
		{
		if((argv[1][i]<'A')||((argv[1][i]>'Z')&&(argv[1][i]<'a'))||(argv[1][i]>'z'))
		{
			printf("Error, the charactor must be 'A'-'Z' or 'a'-'z'\n");
			return 0;
		}
		}
		/* Create an unnamed socket for the server. */
		server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

		/* Assign a name to a socket. */
		server_address.sin_family = AF_INET;
		server_address.sin_addr.s_addr = inet_addr("192.168.1.245");
		server_address.sin_port = 6;
		server_len = sizeof(server_address);
		result = bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
		if(result == -1)
		{
			perror("OOPS!!: bind function error\n");
			exit(1);
		}
			
		/* Create a connection queue and wait for clients. */
		result = listen(server_sockfd, 7);
		if(result == -1)
		{
			perror("OOPS!!: listen function error\n");
			exit(1);
		}	
	
		while(1)
		{
			printf("server waiting round: %02d\n", round);
			round++;

			/* Accept a connection. */
			client_len = sizeof(client_address);
		client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);

             answer = 0;
			// Receive memory 
			result = read(client_sockfd, &nB, sizeof(int16u));
			if(result == -1)
			{
				write(client_sockfd,&answer,sizeof(int16u));
				printf("Read memory error\n");
			}
			else
			{
				// Answer to client
				answer = 1;
				write(client_sockfd,&answer,sizeof(int16u));
				answer = 0;
				// Receive string
				buf = (int8u*)malloc(nB*(sizeof(int8u)));
				result = read(client_sockfd,buf,nB*(sizeof(int8u)));
				if(result == -1)
				{
					write(client_sockfd,&answer,sizeof(int16u));
					printf("Read string error\n");
				}
				else
				{	
					// find the match charactor
					j = 0;
					for(i=0;buf[i]!='\0';i++)
					{
	                    if((buf[i]==argv[1][j])||(buf[i]==argv[1][j]-32)||(buf[i]==argv[1][j]+32))
						{
							buf[i] = argv[1][j];
							j++;
						}
						else
						{
							buf[i] = '*';
						}
					}
					
					if(j != strlenge(argv[1])-1)
					{
						// String not match.Answer to client
						answer = 2;
						write(client_sockfd,&answer,sizeof(int16u));
						answer = 0;
					}
					else
					{
						answer = 1;
						write(client_sockfd,&answer,sizeof(int16u));
						answer = 0;
						read(client_sockfd,&answer,sizeof(int16u));
						if(answer)
						{
						// send back to client
						write(client_sockfd,buf,strlenge(buf)*(sizeof(int8u)));
						}
					}
					free(buf);
				}
			}
			/* Close socket. */
			close(client_sockfd);
		}
	}
	else
	{
		printf("Error, the number of argument must be 2.\n");
	}

}

/****************************************************************************/
/**                                                                        **/
/** EOF                                                                    **/
/**                                                                        **/
/****************************************************************************/
 
